package cn.zl.common.manage;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.zl.common.manage.dashboard.CPUDashboard;
import cn.zl.common.manage.dashboard.DiskDashboard;
import cn.zl.common.manage.dashboard.MemoryDashboard;
import cn.zl.common.manage.dashboard.NetworkDashboard;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import oshi.SystemInfo;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.OperatingSystem;

import java.io.File;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Component
public class DashboardManage {

    private static final Logger logger = LoggerFactory.getLogger(DashboardManage.class);

    private final SystemInfo si;
    // CPU
    private final CPUDashboard cpu;
    // 内存
    private final MemoryDashboard memory;
    // 磁盘
    private final DiskDashboard disk;
    // 网络
    private final NetworkDashboard network;

    public DashboardManage(){
        si = new SystemInfo();
        cpu = new CPUDashboard(si);
        memory = new MemoryDashboard(si);
        disk = new DiskDashboard(si);
        network = new NetworkDashboard(si);
    }

    @Scheduled(fixedRate = 1000)
    public void execute() {
        String now = LocalDateTimeUtil.format(LocalDateTime.now(), "HH:mm:ss");
        this.getCpuDashboard(now);
        this.getMemoryDashboard(now);
        this.getDiskDashboard();
        this.getNetworkDashboard(now);
        if(logger.isTraceEnabled()){
            logger.trace("cpu: {}", cpu);
            logger.trace("memory: {}", memory);
            logger.trace("disk: {}", disk);
            logger.trace("network: {}", network);
        }
    }

    private void getCpuDashboard(String now) {
        // 获取当前系统的进程信息
        OperatingSystem os = si.getOperatingSystem();
        // 进程数量
        this.cpu.setProcessorNum(os.getProcessCount());

        OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
        this.cpu.addRate(now, (int) operatingSystemMXBean.getSystemLoadAverage() * 100);
    }

    private void getMemoryDashboard(String now) {
        // 获取硬件抽象层对象
        HardwareAbstractionLayer hal = si.getHardware();
        // 获取内存信息对象
        GlobalMemory memory = hal.getMemory();
        this.memory.setTotal(memory.getTotal());
        this.memory.setAvailable(memory.getAvailable());
        this.memory.setUsed(memory.getTotal() - memory.getAvailable());
        int rate = (int) ((memory.getTotal() - memory.getAvailable()) * 100.0 / memory.getTotal());
        this.memory.addRate(now, rate);
    }

    private void getDiskDashboard() {
        String os = System.getProperty("os.name").toLowerCase();
        List<String> paths = new ArrayList<>();
        if (os.contains("win")) {
            paths.add("C:");
            paths.add("D:");
            paths.add("E:");
            paths.add("F:");
            paths.add("G:");
            paths.add("H:");
        } else if (os.contains("linux")) {
            paths.add("/");
            paths.add("/home");
        } else {
            paths.add("/");
        }
        for (String path : paths) {
            File file = new File(path);
            long totalSpace = file.getTotalSpace();
            if(totalSpace>0){
                this.disk.add(path, file.getTotalSpace(), file.getUsableSpace());
            }
        }
    }

    private void getNetworkDashboard(String now){
        network.getNetworkInfo(now);
    }

    public CPUDashboard getCpu() {
        return cpu;
    }

    public MemoryDashboard getMemory() {
        return memory;
    }

    public DiskDashboard getDisk() {
        return disk;
    }

    public NetworkDashboard getNetwork() {
        return network;
    }
}
